﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class PUEXDynamicAttribute {

	public enum DynamicAttributeType
	{
		DAT_FIXED,
		DAT_RANDOM,
		DAT_CURVED,
	}

	public DynamicAttributeType type;

	// 									[DAT_FIXED]					| [DAT_RANDOM]				| [DAT_CURVED]				
	public string paramName = "";		// valueParamName			| minParamName				| curveBaseValueParamName	
	public string param2Name = "";		// 							| maxParamName				| curveMapValueParamName	
	public float value;					// value					| min						| baseValue					
	public float value2;				// 							| max						| mapValue					
	public AnimationCurve curve;		// 							| 							| curve

	public static PUEXDynamicAttribute GenerateFixed (float value)
	{
		PUEXDynamicAttribute dat = new PUEXDynamicAttribute ();
		dat.type = DynamicAttributeType.DAT_FIXED;
		dat.value = value;
		return dat;
	}

	public static PUEXDynamicAttribute GenerateRandom (float min, float max)
	{
		PUEXDynamicAttribute dat = new PUEXDynamicAttribute ();
		dat.type = DynamicAttributeType.DAT_RANDOM;
		dat.value = min;
		dat.value2 = max;
		return dat;
	}

	public static PUEXDynamicAttribute GenerateCurved (float curveBeginValue, float curveEndValue)
	{
		PUEXDynamicAttribute dat = new PUEXDynamicAttribute ();
		dat.type = DynamicAttributeType.DAT_CURVED;
		dat.curve = AnimationCurve.Linear(0f, curveBeginValue, 1f, curveEndValue);
		return dat;
	}
	
	public PUEXDynamicAttribute ()
	{
		// default
		type = DynamicAttributeType.DAT_FIXED;
		value = 0f;
		value2 = 1f;
	}

	public void parameterize (PUEXParticleSystem system)
	{
		switch (type) {
		case DynamicAttributeType.DAT_FIXED:
			if (system.dynParams.ContainsKey (paramName))
				value = system.dynParams [paramName];
			break;
		case DynamicAttributeType.DAT_RANDOM:
			if (system.dynParams.ContainsKey (paramName))
				value = system.dynParams [paramName];
			if (system.dynParams.ContainsKey (param2Name))
				value2 = system.dynParams [param2Name];
			break;
		case DynamicAttributeType.DAT_CURVED:
			if (system.dynParams.ContainsKey (paramName))
				value = system.dynParams [paramName];
			if (system.dynParams.ContainsKey (param2Name))
				value2 = system.dynParams [param2Name];
			break;
		}
	}
	
	public float getValue (float t)
	{
		switch (type) {
		case DynamicAttributeType.DAT_FIXED:
			return value;
		case DynamicAttributeType.DAT_RANDOM:
			return Random.Range(value, value2);
		case DynamicAttributeType.DAT_CURVED:
			return value + curve.Evaluate (t) * value2;
		}
		return 0f;
	}

}

[System.Serializable]
public class PUEXDynamicTrigger {

	public string triggerBaseValueParamName = "";
	public string triggerScaleValueParamName = "";
	public float baseValue;
	public float scaleValue;
	public AnimationCurve curve;
	
	protected float _lastValue;
	
	public PUEXDynamicTrigger ()
	{
		// default
		baseValue = 0f;
		scaleValue = 1f;
		curve = AnimationCurve.Linear(0f, 0f, 1f, 0f);
		
		_lastValue = 0f;
	}
	
	public void parameterize (PUEXParticleSystem system)
	{
		if (system.dynParams.ContainsKey (triggerBaseValueParamName))
			baseValue = system.dynParams [triggerBaseValueParamName];
		if (system.dynParams.ContainsKey (triggerScaleValueParamName))
			scaleValue = system.dynParams [triggerScaleValueParamName];
	}
	
	public bool isTrigger (float t, out float value)
	{
		float v = baseValue + curve.Evaluate (t * scaleValue);
		
		bool trigger = false;
		if (_lastValue <= 0f && v > 0f)
			trigger = true;
		
		_lastValue = v;

		value = v;
		return trigger;
	}
}

[System.Serializable]
public class PUEXDynamicColor {

	public enum DynamicColorType
	{
		DCT_FIXED,
		DCT_RANDOM,
		DCT_GRADIENT,
	}
	
	public DynamicColorType type;
	
	// 									[DCT_FIXED]					| [DCT_RANDOM]				| [DCT_GRADIENT]				
	public string paramName = "";		// colorParamName			| colorStartParamName		| 	
	public string param2Name = "";		// 							| mcolorEndParamName		| 	
	public Color value;					// color					| colorStart				| 					
	public Color value2;				// 							| colorEnd					| 					
	public Gradient gradient; 			// 							| 							| gradient

	public static PUEXDynamicColor GenerateFixed ()
	{
		PUEXDynamicColor dct = new PUEXDynamicColor ();
		dct.type = DynamicColorType.DCT_FIXED;
		return dct;
	}
	
	public static PUEXDynamicColor GenerateRandom ()
	{
		PUEXDynamicColor dct = new PUEXDynamicColor ();
		dct.type = DynamicColorType.DCT_RANDOM;
		return dct;
	}
	
	public static PUEXDynamicColor GenerateGradient ()
	{
		PUEXDynamicColor dct = new PUEXDynamicColor ();
		dct.type = DynamicColorType.DCT_GRADIENT;
		return dct;
	}
	
	public PUEXDynamicColor ()
	{
		// default
		value = Color.white;
		value2 = Color.black;
	}
	
	public void parameterize (PUEXParticleSystem system)
	{
		switch (type) {
		case DynamicColorType.DCT_FIXED: {
			string rn = paramName + ".r";
			string gn = paramName + ".g";
			string bn = paramName + ".b";
			string an = paramName + ".a";
			if (system.dynParams.ContainsKey (rn) &&
			    system.dynParams.ContainsKey (gn) &&
			    system.dynParams.ContainsKey (bn) &&
			    system.dynParams.ContainsKey (an)) {
				value = new Color(system.dynParams [rn], system.dynParams [gn], system.dynParams [bn], system.dynParams [an]);
			}
			break;
		}
		case DynamicColorType.DCT_RANDOM: {
			string rn = paramName + ".r";
			string gn = paramName + ".g";
			string bn = paramName + ".b";
			string an = paramName + ".a";
			if (system.dynParams.ContainsKey (rn) &&
			    system.dynParams.ContainsKey (gn) &&
			    system.dynParams.ContainsKey (bn) &&
			    system.dynParams.ContainsKey (an)) {
				value = new Color(system.dynParams [rn], system.dynParams [gn], system.dynParams [bn], system.dynParams [an]);
			}

			string rn2 = paramName + ".r";
			string gn2 = paramName + ".g";
			string bn2 = paramName + ".b";
			string an2 = paramName + ".a";
			if (system.dynParams.ContainsKey (rn2) &&
			    system.dynParams.ContainsKey (gn2) &&
			    system.dynParams.ContainsKey (bn2) &&
			    system.dynParams.ContainsKey (an2)) {
				value2 = new Color(system.dynParams [rn2], system.dynParams [gn2], system.dynParams [bn2], system.dynParams [an2]);
			}
			break;
		}
		case DynamicColorType.DCT_GRADIENT:
			break;
		}
	}
	
	public Color getColor (float t)
	{
		switch (type) {
		case DynamicColorType.DCT_FIXED:
			return value;
		case DynamicColorType.DCT_RANDOM:
			float rnd = Random.value;
			return Color.Lerp(value, value2, rnd);
		case DynamicColorType.DCT_GRADIENT:
			return gradient.Evaluate(t);
		}
		return Color.red;
	}
}
